home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
cstdio.arc
/
SRC.ARC
/
MEMALL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1985-05-17
|
3KB
|
121 lines
/* memall.c - main memory allocator.
From K & R pages 173 - 177.
Entered - G. R. Mansfield. 84/07/31.
Ver 1.0-5517.
*/
#include <defstd.h>
#define NALLOC 128 /* units to allocate at once */
typedef int ALIGN; /* forces alignment in 8086 */
union header { /* free block header */
struct {
union header *ptr; /* next free block */
unsigned size; /* size of this free block */
} s;
ALIGN x;
};
typedef union header HEADER;
/* local functions */
static HEADER *moremem();
/* local data */
static HEADER base; /* empty list to get started */
static HEADER *allocp = NULL; /* last allocated block */
static HEADER *moremem();
BYTE *malloc(nbytes) /* general-purpose storage allocator */
unsigned nbytes;
{
register HEADER *p, *q;
register int nunits;
BYTE *bp;
int i, j;
nunits = 1+(nbytes+sizeof(HEADER)-1)/sizeof(HEADER);
if ((q = allocp) == NULL) { /* no free list yet */
base.s.ptr = allocp = q = &base;
base.s.size = 0;
}
for (p = q->s.ptr; ; q = p, p = p->s.ptr) {
if (p->s.size >= nunits) { /* big enough */
if (p->s.size == nunits) /* exactly */
q->s.ptr = p->s.ptr;
else { /* allocate tail end */
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
p->s.ptr = NULL;
}
allocp = q;
return((BYTE *)(p+1));
}
if (p == allocp) /* wrapped around free list */
if ((p = moremem(nunits)) == NULL)
return(NULL); /* none left */
}
}
BYTE *calloc(nelem, elsize)
unsigned nelem, elsize;
{
BYTE *p, *q;
unsigned n;
n = nelem * elsize;
if ((p = q = malloc(n)) == NULL)
return(NULL);
while (n--)
*q++ = 0;
return(p);
}
static HEADER *moremem(nu) /* ask system for memory */
unsigned nu;
{
BYTE *sbrk();
register BYTE *cp;
register HEADER *up;
register int rnu;
rnu = NALLOC * ((nu+NALLOC-1) / NALLOC);
cp = sbrk(rnu * sizeof(HEADER));
/*printf("cp %04x\n", cp);*/
if ((int)cp == -1) /* no space at all */
return(NULL);
up = (HEADER *)cp;
up->s.size = rnu;
free((BYTE *)(up+1));
return(allocp);
}
free(ap) /* put block ap in free list */
BYTE *ap;
{
register HEADER *p, *q;
p = (HEADER *)ap - 1; /* point to header */
/*printf("free ap %04x p %04x, s %04x ", p, p->s.ptr, p->s.size);*/
for (q=allocp; !(p > q && p < q->s.ptr); q=q->s.ptr)
if (q >= q->s.ptr && (p > q || p < q->s.ptr))
break; /* at one end or other */
if (p+p->s.size == q->s.ptr) { /* join to upper nbr */
p->s.size += q->s.ptr->s.size;
p->s.ptr = q->s.ptr->s.ptr;
} else
p->s.ptr = q->s.ptr;
if (q+q->s.size == p) { /* join to lower nbr */
q->s.size += p->s.size;
q->s.ptr = p->s.ptr;
} else
q->s.ptr = p;
allocp = q;
/*printf("fp %04x p %04x, s %04x ", p, p->s.ptr, p->s.size);
printf("fq %04x p %04x, s %04x\n", q, q->s.ptr, q->s.size);*/
}